上一篇我們有提到頁面傳入 Model 為 DTO,Service 回傳 ViewModel。
類別的對應轉換時常是一件很麻煩的事。例如下圖
public IEnumerable<UserViewModel> GetUser(UserDTO m)
{
var data = GetUserByAccName(m);
var result = data.Select(x => new UserViewModel()
{
Name = x.Name,
Account = x.Account,
Email = x.Email,
Role = x.Role,
Note = x.Note,
});
return result;
}
或者是
public IEnumerable<UserViewModel> GetUser(UserDTO m)
{
var data = GetUserByAccName(m);
List<UserViewModel> result = new List<UserViewModel>();
foreach (var i in data)
{
UserViewModel viewModel = new UserViewModel();
viewModel.Name = i.Name;
viewModel.Account = i.Account;
viewModel.Email = i.Email;
viewModel.Role = i.Role;
viewModel.Note = i.Note;
result.Add(viewModel);
}
return result;
}
有沒有覺得,這樣的轉換非常麻煩,而且上面的範例只有五個欄位的轉換,如果今天是十個或者更多,那應該是非常得眼花撩亂,這時候就要介紹強大的AutoMapper
。
AutoMapper
的使用很簡單,就三個步驟
1.設定 Model 之間的轉換
2.建立 Mapper
3.透過 Map 方法轉換型別
public IEnumerable<UserViewModel> GetUser(UserDTO m)
{
var data = GetUserByAccName(m);
var config = new MapperConfiguration(cfg =>
cfg.CreateMap<UserDTO, UserViewModel>());
var mapper = config.CreateMapper();
var result = mapper.Map<IEnumerable<UserViewModel>>(data);
return result;
}
有沒有發現程式碼行數不但變少了,整個程式碼看起來也很好懂!但你可能會疑惑,他是如何對應的呢?
AutoMapper 會將兩個類別相同名稱的屬性內容做轉換
那如果今天名稱不同,又或者是要合併顯示該如何處理呢?
*假設我的 ViewModel 的 Name 想要帳號+空白+名字
public IEnumerable<UserViewModel> GetUser(UserDTO m)
{
var data = GetUserByAccName(m);
var config = new MapperConfiguration(cfg =>
cfg.CreateMap<UserDTO, UserViewModel>()
.ForMember(x => x.Name, y => y.MapFrom(o => $"{o.Account} {o.Name}")));
var mapper = config.CreateMapper();
var result = mapper.Map<IEnumerable<UserViewModel>>(data);
return result;
}
有時候我們會遇到沒有對應的欄位,例如 資料回來的 ViewModel 有 LoginTime 欄位,但傳入的 DTO 沒有,這時候如果用上面的方法,會造成轉換錯誤,所以我們必須 Ignore
LoginTime欄位
public IEnumerable<UserViewModel> GetUser(UserDTO m)
{
var data = GetUserByAccName(m);
var config = new MapperConfiguration(cfg =>
cfg.CreateMap<UserDTO, UserViewModel>()
.ForMember(x => x.Account, y => y.MapFrom(o => $"{o.Account} {o.Name}"))
.ForMember(x => x.LoginTime, y => y.Ignore())); //忽略掉不轉換
var mapper = config.CreateMapper();
var result = mapper.Map<IEnumerable<UserViewModel>>(data);
return result;
}
到這邊你可能會疑惑,怎麼感覺越來越多行了,那所謂的簡化呢?不要急,我們下一篇來介紹
那今天就到這邊囉,大家明天見!